﻿using Behaving.Composites;
using FluentAssertions;
using NUnit.Framework;

namespace Behaving.Tests
{
    [TestFixture]
    public class MiscTests
    {
        private ExecutionCounter _before;
        private ExecutionCounter _after;
        private ExecutionCounter _inner;
        private ExecutionCounter _pre;

        [Test]
        public void Test()
        {
            BehaviourTree bt = BuildTree();

            bt.Tick();
            Assertions.AssertWasStartedAndExecuted(_before);
            Assertions.AssertWasNotCalled(_inner);
            Assertions.AssertWasNotCalled(_after);
            ResetAll();

            _before.RunningState = RunningState.Success;
            bt.Tick();
            Assertions.AssertWasExecutedAndStopped(_before);
            Assertions.AssertWasStartedAndExecuted(_inner);
            Assertions.AssertWasNotCalled(_after);

            ResetAll();
            bt.Tick();
            Assertions.AssertWasNotCalled(_before);
            Assertions.AssertWasExecuted(_inner);
            Assertions.AssertWasNotCalled(_after);

            ResetAll();
            _inner.RunningState = RunningState.Failure;
            bt.Tick();
            Assertions.AssertWasNotCalled(_before);
            Assertions.AssertWasExecutedAndStopped(_inner);
            Assertions.AssertWasNotCalled(_after);

            ResetAll();
            _inner.RunningState = RunningState.Failure;
            bt.Tick();
            Assertions.AssertWasStartedExecutedAndStopped(_before);
            Assertions.AssertWasStartedExecutedAndStopped(_inner);
            Assertions.AssertWasNotCalled(_after);
        }

        private void ResetAll()
        {
            _pre.Reset();
            _before.Reset();
            _inner.Reset();
            _after.Reset();
        }

        private BehaviourTree BuildTree()
        {            
            BehaviourTree bt =
                new BehaviourTree(
                    new PriortySelector(
                        _pre = new ExecutionCounter(RunningState.Failure),
                        new Sequence(
                            _before = new ExecutionCounter(RunningState.Running),
                            _inner = new ExecutionCounter(RunningState.Running),
                            _after = new ExecutionCounter(RunningState.Running))));
            return bt;
        }
    }
}